﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace Zero.UControl.Component
{
    public class CaptchaControl : Control
    {
        private static readonly Random _rand = new Random();
        private string _captchaText = "";

        public string CaptchaText => _captchaText;

        public int CharacterCount { get; set; } = 6;
        public int FontSizeRangeMin { get; set; } = 20;
        public int FontSizeRangeMax { get; set; } = 32;

        public CaptchaControl()
        {
            Width = 180;
            Height = 50;
            Cursor = Cursors.Hand;
            Background = new SolidColorBrush(Colors.Transparent);
            MouseLeftButtonDown += (s, e) =>
            {
                GenerateCaptcha();
                InvalidateVisual();
            };
            GenerateCaptcha();
        }

        private void GenerateCaptcha()
        {
            const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
            _captchaText = "";

            for (int i = 0; i < CharacterCount; i++)
            {
                _captchaText += chars[_rand.Next(chars.Length)];
            }
        }

        protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);

            // 背景
            dc.DrawRectangle(Background, new Pen(new SolidColorBrush(Colors.Black), 2), new Rect(0, 0, ActualWidth, ActualHeight));

            // 干扰线
            for (int i = 0; i < 6; i++)
            {
                var p1 = new Point(_rand.Next(2, (int)(ActualWidth - 2)), _rand.Next(3, (int)(ActualHeight - 3)));
                var p2 = new Point(_rand.Next(2, (int)(ActualWidth - 2)), _rand.Next(3, (int)(ActualHeight - 3)));

                var color = Color.FromArgb(
                    128,
                    (byte)_rand.Next(50, 200),
                    (byte)_rand.Next(50, 200),
                    (byte)_rand.Next(50, 200));
                var pen = new Pen(new SolidColorBrush(color), 2);
                dc.DrawLine(pen, p1, p2);
            }

            // 干扰点
            for (int i = 0; i < 50; i++)
            {
                var point = new Point(_rand.Next(5, (int)(ActualWidth - 5)), _rand.Next(5, (int)(ActualHeight - 5)));
                var color = Color.FromRgb(
                   (byte)_rand.Next(80, 255),
                   (byte)_rand.Next(80, 255),
                   (byte)_rand.Next(80, 255));
                var brush = new SolidColorBrush(color);
                dc.DrawEllipse(brush, null, point, 1.6, 1.6);
            }

            // 画验证码字符
            double charWidth = ActualWidth / CharacterCount;
            for (int i = 0; i < _captchaText.Length; i++)
            {
                string c = _captchaText[i].ToString();
                double fontSize = _rand.Next(FontSizeRangeMin, FontSizeRangeMax);

                var color = Color.FromRgb(
                   (byte)_rand.Next(20, 156),
                   (byte)_rand.Next(20, 156),
                   (byte)_rand.Next(20, 156));
                var brush = new SolidColorBrush(color);

                FormattedText ft = new FormattedText(
                    c,
                    System.Globalization.CultureInfo.CurrentCulture,
                    FlowDirection.LeftToRight,
                    new Typeface("Arial"),
                    fontSize,
                    brush,
                    VisualTreeHelper.GetDpi(this).PixelsPerDip);

                double x = i * charWidth + _rand.NextDouble() * (charWidth - ft.Width);
                double y = (ActualHeight - ft.Height) / 2 + _rand.NextDouble() * 5;

                // 旋转一定角度
                double angle = _rand.Next(-30, 30);
                dc.PushTransform(new RotateTransform(angle, x + ft.Width / 2, y + ft.Height / 2));
                dc.DrawText(ft, new Point(x, y));
                dc.Pop();
            }
        }
    }

}
